﻿using GN.Data.Entity.Attribute;
using System;

namespace GN.Data.Entity
{
    public class EntityModel : Object
    {
        /// <summary>
        /// 错误信息
        /// </summary>
        public string ValidationMessage = string.Empty;

        /// <summary>
        /// 验证当前数据模型
        /// </summary>
        public bool IsValid()
        {
            System.Reflection.PropertyInfo[] info = this.GetType().GetProperties();
            foreach (var item in info)
            {
                var desc = (DescriptionAttribute[])item.GetCustomAttributes(typeof(DescriptionAttribute), false);
                string _field = "_";
                if (desc.Length == 1)
                    _field = desc[0].Display;
                else
                    _field = item.Name;

                BaseAttribute[] attributes = (BaseAttribute[])item.GetCustomAttributes(typeof(BaseAttribute), true);
                foreach (var itm in attributes)
                {
                    switch (itm.GetType().Name)
                    {
                        case "RequireAttribute":
                            {
                                RequireAttribute attr = (RequireAttribute)itm;
                                object val = item.GetValue(this, null);
                                ValidationMessage = _field + attr.ErrMsg;
                                if (string.IsNullOrWhiteSpace(val + ""))
                                {
                                    return false;
                                }
                                break;
                            }
                        case "StringLengthAttribute":
                            {
                                StringLengthAttribute attr = (StringLengthAttribute)itm;
                                object val = item.GetValue(this, null);
                                if (val != null && val.ToString().Length > attr.MaximumLength)
                                {
                                    ValidationMessage = _field + attr.ErrMsg;
                                    return false;
                                }
                                else if (val != null && val.ToString().Length < attr.MinimumLength)
                                {
                                    ValidationMessage = _field + attr.ErrMsg;
                                    return false;
                                }
                                break;
                            }
                        case "RegexRegularAttribute":
                            {
                                RegexRegularAttribute attr = (RegexRegularAttribute)itm;
                                object val = item.GetValue(this, null);
                                ValidationMessage = _field + attr.ErrMsg;
                                if (attr.IsEmail)
                                {
                                    return attr.IsMailMatch(val == null ? string.Empty : val.ToString());
                                }
                                if (attr.IsPhone)
                                {
                                    return attr.IsPhoneMatch(val == null ? string.Empty : val.ToString());
                                }
                                return attr.IsMatch(val == null ? string.Empty : val.ToString());
                                break;
                            }
                        case "NumericAttribute":
                            {
                                NumericAttribute attr = (NumericAttribute)itm;
                                int val = (int)item.GetValue(this, null);
                                ValidationMessage = _field + attr.ErrMsg;
                                if (attr.Min != int.MinValue && val < attr.Min)
                                {
                                    return false;
                                }
                                else if (attr.Max != int.MaxValue && val > attr.Max)
                                {
                                    return false;
                                }
                                break;
                            }
                        default:
                            break;
                    }
                }
            }
            return true;
        }
    }
}
